home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
HEAP_UTL
/
HDEB20S
/
README.TXT
< prev
next >
Wrap
Text File
|
1995-04-17
|
45KB
|
978 lines
The
HEAP DEBUGGER V2.0
for
BORLAND PASCAL V7.0
(DOS, DOS/DPMI, WINDOWS)
Copyright 1995
by
AIT GmbH
Alte Gasse 12 - 86152 Augsburg
Germany
Tel. +49 (821) 514868
Fax: +49 (821) 514831
FIDO-Net: Karsten Strobel @ 2:2480/300.7
Internet: kstrobel@gewi.muc.nacamar.de
CONTENTS
INTRUDUCTION
Why Heap Debugging ? ................................................ 3
What the Heap Debugger CAN do........................................ 3
What the Heap Debugger CANNOT do .................................... 3
The usage of Dynamic Memory ......................................... 3
Versions and Targetplatforms ........................................ 4
List of the Files ................................................... 5
Shareware Concept ................................................... 5
Licence Conditions .................................................. 5
Usertips and Warranty Limitation .................................... 6
USING THE HEAP DEBUGGER
Linking the Heap Debugger ........................................... 6
Compiler- and Linkeradjustments ..................................... 6
When the Initialization fails ....................................... 7
The Heap Debugger Report ............................................ 7
Special Messages in the Heap Debugger Report ........................ 9
Interpretation of the Report ......................................... 9
Hunting for Bugs .................................................... 10
Working with the External Debugger .................................. 11
Compilerswitches in USEHDEB ......................................... 11
HEAP DEBUGGING IN DETAIL
Overlays ............................................................ 12
DLLs ................................................................ 12
Program instances (Windows) ......................................... 13
Interrupts .......................................................... 13
Stability and Performance ........................................... 13
Intervention possibilities for the Programmer ....................... 14
KNOWN LIMITATIONS AND PROBLEMS
Mark/Release ........................................................ 15
MemAllocSeg ......................................................... 15
BGI ................................................................. 16
TMemoryStream ....................................................... 16
Heap Overrun ........................................................ 17
Program Halt ........................................................ 17
WINCRT .............................................................. 17
Page 3
INTRODUCTION____________________________________________________________
___ Why Heap Debugging ? _______________________________________________
The Heap Debugger controls (nearly) all by the program preformed heap
operations and writes among other things a list of all heap memory
areas that were not released. The programmer, who uses the Heap Debug-
ger while developing his program, will be notified about the remaining
Memoryblocks after every ending of his program.
The Heap Debugger makes the finding of mistakes extremely easy, because
it gives (often) a note about the source code location (file name and
line number), where incorrect heap operations were preformed, or where
a not released memory block was allocated.
Herefor the Heap Debugger uses the debug information for the external
Debugger, that (optionally) the is created by the compiler and that
extends the EXE-files.
___ What the Heap Debugger CAN do ______________________________________
The Heap Debugger controls all allocations of meap memory, that are
performed with the commands
- GetMem
- New
- FreeMem
- Dispose
Also calls of these routines from within the runtime-library and from
program-parts, that are not available in sourcecode (for example
foreign TPU's) are considered.
All non correct deallocated heap memory blocks and other false heap
operations are listed in the Heap Debugger Report.
___ What the Heap Debugger CANNOT do ___________________________________
The following heap operations cannot be controlled by the Heap Debugger:
- Mark and Release (are not allowed to be used !)
- direct access to the global heap (DPMI+Windows),
so all "Global..."-calls
- direct access to the local heap (Windows),
so all "Local..."-calls
___ The Usage of Dynamic Memory _______________________________________
In programs, that uses heap memory intensively, not seldom treacherous
programming errors are made: when dynamicly requested memory blocks
are not released correctly, the available heap memory stepwise
shrinks all together, so that sometime for a new request not enough
space remains and the program may stop or collapse.
Page 4
It only comes to a complete consumption of the heap memory, when
allocations without deallocating, not only once, but again and again
are preformed. Such allocations could work a few hundret times until the
whole heap memory is used up. So such crashes will normally happen later
to the user, who of course does not know why.
There are also allocations, that only once, so for instance in the
initialg process are done, because the program uses heap memory space
for quasi-static variables. The programmer could allocate such variables
(respectively structures or objects) into the data segment (as global
variables), but since the size of the data segment is limited to
a total of 64KB, he will sometimes misuse the Heap as a way out. When
such (only once allocated) quasi-static variables are not released, then
this is only a disfigurement, and has no other consequences. The Heap
Debugger criticizes of course also such offences.
Particularly treacherous are deallocation errors, that means incorrect
released memory. A deallocation error is when with the releasing of
heap memory a false address or a false length is directed, so to the
undertaken deallocation no allocation was processed before. Since the
runtime-library mostly relies upon the information the programmer gives,
deallocation errors can have disastrous consequences.
Especially the object oriented programming makes intensively use of heap
memory. For every new dynamic instance of an object type there will be a
heap allocated for the fields of the object, that when deleting then
object instance must be released. Herefor you use the commands NEW and
DISPOSE in the for OOP-use extended syntax. Also forgotten objects
consume heap memory.
___ Versions and Targetplatforms _______________________________________
The Heap Debugger was developed and tested with
Borland Pascal V7.0 and V7.01
with the target systems
- Real Mode (for this HDEB7?.TPU)
- Protected Mode (for this HDEB7?.TPP)
- Windows (for this HDEB7?.TPW)
under
- DOS 6.2x
- Windows V3.1
- Windows for Workgroups V3.11
- Windows NT 3.5 Workstation
- OS/2 V2.11.
A Version for Delphi V1.0 for Windows is be prepared.
Page 5
___ List of the Files __________________________________________________
USEHDEB.PAS .... Unit to link to your pascal program, for
DOS, DOS/DPMI and WINDOWS
HDEB7S.TPU ..... The core of the Heap Debugger,
shareware version, for DOS/Real Mode
HDEB7S.TPP ..... The core of the Heap Debugger,
shareware version, for DOS/Protected Mode
HDEB7S.TPW ..... The core of the Heap Debugger,
shareware version, for Windows
HDEB7F.TPU ..... The core of the Heap Debugger,
registered version, for DOS/Real Mode
HDEB7F.TPP ..... The core of the Heap Debugger,
registered version, for DOS/Protected Mode
HDEB7F.TPW ..... The core of the Heap Debugger,
registered version, for Windows
VIEWME.EXE ..... The Heap Debugger in pictures (sliteshow, req. VGA)
README.TXT ..... This text (english)
LIESMICH.TXT ... This text (german, in mare correct grammer!)
DIZFILES.ZIP ... Short description-files, for Sysops
SHARWARE.ZIP ... This file only conmes with registered versions and
contains the sharewareversion
BESTELL.TXT .... Orderform (german)
ORDER.TXT ...... Orderform (english)
___ Shareware Concept __________________________________________________
The Heap Debugger is Shareware, not Public Domain or Freeware!
The through the shareware distributers delivered version of the Heap
Debugger with the files HDEB7S.* ("S"=Shareware) and the accompanied
files and the file USEHDEB.PAS are allowed to be used for test purposes
and are allowed to be distributed freely.
The shareware version is towards the registered version in its capacity
limited: The shareware version of the Heap Debugger controls only the
first 50 allocations of memory blocks. All following allocations will be
ignored. When exceeding the shareware limit there will come an
appropriate message in the report (at the end of the program).
Registered versions of the Heap Debuggers contain the files HDEB7F.*
("F"=Full). These files are not allowed to be distributed to third, or
to be made available for them.
___ Licence Conditions _________________________________________________
If you want to use the Heap Debugger in the unlimited version, you have
to register. With the delivery of the software you will receive a
licence for the usage on a single workstation.
If you want to use the Heap Debugger on several workstations then you
have to register for every Workstation. Herefor we offer cheaper prices.
A registration form is in the file ORDER.TXT prepared.
Distribution of the registered version of the Heap Debugger is absolutely
prohibited. Especially the files HDEB7F.* must not be delivered to
thirds.
Page 6
___ Usertips and Warranty Limitations __________________________________
Although we tested the Heap Debugger in detail before publishing, we
cannot give a guarantee for error-free function of this software.
We suggest the usage of the Heap Debugger only during the developing
phase.
The Heap Debugger shall help you in your software development to avoid
errors with the memory managment or delete them. We point to the
additional dangers of the stability of a software, that involves the
Heap Debugger. More information is given in the section "Stability and
Performance".
For registered versions of the Heap Debugger we warrant the physical
media to be readable. We specifically disclaim all other warranties!
Using the Heap Debugger ________________________________________________
___ Linking the Heap Debugger __________________________________________
To link the Heap Debugger into your program, you only have to insert
the unit UseHDeb in the uses-clause of your main program. For Example:
PROGRAM MyProg;
UseHDeb,
\ /
\/
USES Drivers, Objects, Views, Menus, ...
It is a good idea, to list the Unit UseHDeb as the first Unit in the
uses-clause. The initialization of the Heap Debugger is done by the
initialization-section of this Unit. After the initialization the Heap
Debugger can "watch" heap operations. That is why the initialization
of UseHDeb should be done before other Units, that possibly already
preform heap operations.
___ Compiler- and Linkeradjustments __________________________________
"D+":
The Heap Debugger will only be initialized when the Unit UseHDeb is
compiled with the option "D+" (debug-informations on). This is caused
by, that almost the whole Unit UseHDeb is excepted from the compilation
with the clause {$IFOPT D+}...{$ENDIF} otherwise. So this switch can be
used to turn the Heap Debugger on and off, alltho theoretic the Heap
Debugger could work without the D+ being turned on.
All other Units, that are integrated in your program and also the main
program need to be compiled with the option D+ turned on, if you want
the to get source code references within the report.
Page 7
"Link-Buffer: Disk" and "Standalone Debugging":
Beside the compiler option D+ the adjustments "Link-Buffer: Disk" and
"Standalone Debugger" are also required. Under Windows the last option
is called "Debug-Info in EXE".
"Unit-Directories: \BP\RTL\WIN" (DOS/DPMI and Windows):
The Unit UseHDeb needs in the protected mode (DOS+Windows) the Unit
WINPROCS. This is found normally in the directory "\BP\RTL\WIN". Since
under DOS this index is normally not adjusted as a Unit-Directory (see
Options-->Directories), you must add this directory to the list of
unit-directories yourself.
___ When the Initialization fails ______________________________________
The initialization of the Heap Debugger is done through the initiali-
zation section of the unit UseHDeb. When it fails the UseHDeb reports
"Unable to initialize the Heap Debugger !" and stops the program with
the command HALT.
The failing of the Initialization can have following reasons:
- You are using a modified runtime-library, that in a for
the Heap Debugger important point does not match with the
original from Borland.
- You are using an operating system or a special tool (e.g.
memory management tool) that wasn't verified to supported.
- You are using an unsupported compiler version.
- There were no free interrupt vectors found. The Heap Debugger
needs three free interrupts. In this case probably our
test method for finding free interrupts did fail. It is
extremely rare that all interrupts are really used.
- The Heap Debugger is already initialized. This should not
happen when you use the Unit UseHDeb.
When in your system the initialization fails, then please try to run
your program within a tested configuration (for instance: MSDOS 6.2 ,
Windows 3.1) without loading any special memory managers or multi-
taskers. Observe if the Heap Debugger can now be initialized in this
configuration.
Please inform us about configuration in, with that the Heap Debugger
could not be used. (if possible per email)
___ The Heap Debugger Report ___________________________________________
The Heap Debugger gives a report when ending a program. This happens in
the exit-procedure of the unit UseHDeb.
The Heap Debugger Report has normally the following structure
(for example:)
Page 8
HEAP DEBUGGER DIAGNOSIS:
2 pointer were registered (*1)
1 debug-entries available (*2)
list (Y/N) ? y
(*3) (*4) (*5) (*6) (*7) |------(*8)------|
No Pointer Size Flags Caller File Line
2 1A41:0000 256 0000[122D]:0044 HEAPBUG.PAS 16
(*1): Here is printed, how many heap allocations the Heap Debugger did
observe in total. This number means no statement about possible
mistakes.
(*2): Here is printed, how many diagnosis lines the Heap Debugger has
available to dump. In the best case this number should always
be "0". Not all but most of the diagnosis lines point towards a
programming error.
(*3): Here is a sequential counter of all in the program done
allocations. With deallocations (Flag "F") this place is empty.
(*4): Here is the addresses of the allocated respectively deallocated
heap memory block printed. This address can vary from program-run
to program-run.
(*5): Here is the size of the allocated respectively deallocated block
printed.
(*6): The here listed Flags have following meanings
(combinations are possible):
none : Its about an allocation, to that no fitting deallocation
was performed.
"O" : Its about an instance-data of an object type. This is the
data area, that is created by the constructor of a object
with every new instance. As caller is the line with the
word "BEGIN" in the costructor given (the line with the
word "END" in the destructor at deallocations).
"F" : This diagnosis line deals with a deallocation (F=free).
What went wrong with this deallocation is explained in one
of the following flags.
"S" : A heap memory block was not in the same blocklength
(S=size) deallocated, with which it was allocated. In this
case, the flag will appear both in the diagnosis lines of
the allocation and of the deallocation.
"M" : To a deallocation there was not a fitting allocation found
(M=mismatch). This means, it was tried, to deallocate a
heap memory block, who's address was not registered by a
previous allocation. This flag appears only together with
the flag "F".
(*7): At this address the heap operation, that this diagnosis line is
about, was called. The segment address is the virtual segment
address and in brackets "[]" the actual segment address. The
virtual segment address is generated by the linker and is the
address relative to the address 0000. The actual segment address
will be given when loading a program and depends on the location,
at which the program is loaded into memory. The virtual address
can be found in the map-file. The actual address can vary from
program-run to program-run.
Page 9
(*8): Here the sourcecode location (file name and line number) ist
shown according to the caller address. It is required that the
debug information exist in the EXE-file. If there are no debug
informations present "No Info" will be printed here. If there
are debug informations present but the sourcecode-line of the
caller address couldn't be found nonetheless, a "?" will be
printed here.
___ Special Messages in the Heap Debugger Report _______________________
The following messages can appear under special circumstances:
"Program stopped by HALT(nnn)"
This message says, that the program was stopped with the command
HALT(nnn). The Exitcode is given with nnn.
"runtime-error nnn at ssss:oooo, file: ________ line: ______"
When the program is stopped through a runtime error, this message will
be present. As additional, useful information the file name and line
number of the error are printed, if this information is available.
"internal error 203 occured in Heap Debugger"
This message means, that the Heap Debugger did not have enough heap
memory to record all heap operations.
"Shareware-limit exceeded!
Only 50 pointers were registered!"
This message will only be printed in the shareware version and tells us
that the shareware limit of 50 controlled allocations was exceeded
during the runtime.
___ Interpretation of the Report _______________________________________
Of course you should attempt to receive the message "0 debug-entries
available", at the end of a program-run. If the Heap Debugger is
continually in action during the development of a application, then an
possibly reported bugs can easly be found, because the error most often
was made during the last changes to the program.
If the matter isn't so easy, then you first need to understand the
diagnosis of the Heap Debugger, to solve the problem.
For this purpose you need to ask yourself following questions:
- Is the number of the diagnosis entries always the same, or does this
number vary?
As far as the number does not vary, then it must have to do with an
error that happens only once a program-run. There are cases, in that
the name error is to strong. Some programs allocate some quasi-static
variables on the Heap, and don't release them at the end. This behavior
is not very nice and should be tried to be avoided; on the other hand
this has no bad consequences.
Page 10
- Can the increase of the number of diagnosis lines have to do with
certain functions of my program?
If the number grows, then you should try to find the obviously
repeated error. Most often this is very easy, when the Heap Debugger
gives for several entries the same caller address. It then appears to
be a error, that always occurs when a certain program function is
executed. You should always get rid of these errors, because they can
cause "loss of memory".
- Are there any Flags in a diagnosis lines?
If not, then this diagnosis denunciats a "classic" error, particulary
a not released "normal" heap memory block, that was allocated with
GetMem or New. The sourcecode reference refers to the location, were
this demand happened.
- Is the Flag "O" present ?
If yes, the Heap Debugger shows an error in relation to an object.
If there is just an "O" entered, then this has to with a not released
dynamic instance of an object, which was set up with the command new
in the OOP-variation. The sourcecode reference does NOT point to this
New-command, but to the line BEGIN in the concerned constructor. If
you found out this, you need to think about where the instances of
this object type is allocated and to and check for the correct
releasement.
- Is th Flag "F" present ?
This flag appears never alone. It means (mostly), that a deallocation
error has occurred. Beside the "F" there will always be a "S" or a
"M", which means, that either a deallocation with a false block length
was called, or that the deallocated memory block has an address,
where no allocation was done.
This diagnosis is either real bad or harmless. The harmless case
is described in the section "MemAllocSeg". If this description doesn't
prove, then there is probably a REAL error, that has to be found,
because it could cause the whole program (also the Heap Debugger) to
crash. This can happen, if the consistency of the heap management
becomes damaged.
___ Hunting for Bugs ___________________________________________________
If the Heap Debugger gives with his diagnosis sourcecode references,
then is the finding of bugs relatively easy.
If instead of a sourcecode reference a "?" is printed, then the under
"Caller" listed address is in an module, that has not debug informations
because is wasn't compiled with the option "D+". Often you can find the
caller in the runtime-library.
You should not let yourself come to the conclusion, that you are not
responsible for the error and that the runtime-library has a Bug. If you
for instance do an allocation with "NewStr" (function of the runtime
Page 11
library) and the requested heap memory block then is not deallocated
afterwards with DisposeStr, then the error is in your program. But the
caller is a line in the function NewStr in the runtime library.
A lot of these problems can be solved, if you recompile the whole run-
time-library with the debug-option. This is only possible with BP7.0
(not with TP7.0). Informations for this you find in Borland's
\BP\RTL\README.
___ Working with the External Debugger _________________________________
In hard cases you should try to find an error with the help of the
external debugger. That makes sense when the Heap Debugger did not
give sourcecode references.
In the external Debugger you should set a breakpoint at the callers
address.
Please notice the difference between the virtual and the actual
segment address, that the Heap Debugger prints.
Attention: The actual segment address of the caller can vary from
program-run to program-run. After loading the Debugger it will mostly
move. Let your program run once or a few times with the loaded debugger
before you set a breakpoint. Use the last given actual segment address.
You can set a breakpoint at any adress function "Breakpoints-At...".
Just enter the caller address and start the segment address AND the
offsetaddress with a "$" for hexadecimal notation.
When you reach a breakpoint, continue the execution stepwise until you
reach an area that you know.
___ Compilerswitches in USEHDEB ________________________________________
In the Unit UseHDeb there are already a few compiler switches established,
that eases the adjustment. We hope, that the most adjustment problems can
be solved, so that you don't need to change the source code.
The Switch "USE_SHAREWARE":
When this switch is defined, the Heap Debugger uses the unit
"HDEB7S.TP?". When it is undefined, then the Units "HDEB7F.TP?" is
integrated. This stands for the registered version of the Heap Debugger
and can of course only be used, if the software was registered. This
switch is correctly adjusted in the delivered shareware or the
registered version and does normally not need to be changed.
The Switch "GERMAN_LANG":
When this switch is defined, the Heap Debugger Report will be given in
german language instead of english.
Page 12
The Switch "GETDEBUGINFO":
When this switch is defined, then the Heap Debugger will try to access
to the debug informations in the EXE-file to find out the file name and
line number for every diagnosis line. This switch should normally stay
active.
The Switch "REPORT_TO_FILE":
When this switch is defined, then the report output will be transferred
into a file. The name of this file in defined in the constant
"DumpFileName" and that is preadjusted to "HEAPDEB.DMP" but can be
changed. The file will be enlarged with every report output. Please
note: When the Heap Debugger because of any reason cannot be initialized
and the switch "REPORT_TO_FILE" is active, then the program will be
stopped with the command "HALT" without any warning (also in the file).
The Switch "SWITCH_TO_LASTMODE":
When this switch is defined, the command "TextMode(LastMode)" will be
executed before the report output starts. The command switches back
into the videomode, that was active at the start of the program. This
can be very helpful when the main program switches to a graphics mode
that isn't BIOS-supported or when textcolors are modified in a way,
that the report in not readable. This switch does nothing under Windows.
Example for turning switches off and on:
active: "{$DEFINE GERMAN_LANG}"
inactive: "{not $DEFINE GERMAN_LANG}"
HEAP DEBUGGING IN DETAIL _______________________________________________
___ Overlays ___________________________________________________________
You can use the Heap Debugger also with programs, that uses overlay-
technics. The Units USEHDEB and HDEB7? cannot be loaded as overlays.
___ DLLs _______________________________________________________________
A DLL can be treated just like a normal self-running program. If a
program, that is using the Heap Debugger, loads a DLL at runtime, then
the Heap Debugger is not active for this DLL. On the other hand a DLL
can use the Heap Debugger, without the heap operations in the main
program being controlled. If the Heap Debugger is used for the DLL and
the main program, then there will be two reports printed.
To link the Heap Debugger to a DLL just insert the unit UseHDeb in the
uses-clause of the librarys main file (with the title "Library").
The exit-procedure of the unit UseHDeb (with the Reportoutput) will be
done when the DLL ends. When is this? The DLL normally ends, when also
the main program, that loaded the DLL, ends. But there are exceptions:
If the main program is run with the external debugger, then the DLL will
not end when the program is ended, but when the debugger is ended, what
Page 13
very often leads to a system crash. We suggest to use the command
"FreeLibrary" to unload a DLL that uses the Heap Debugger. The report
for the DLL will than be printed immediately. What was just described
counts for DLLs under DOS and WINDOWS the same.
Under Windows there is also another problem: The report output, that is
done by the unit UseHDeb under Windows is printed into a WinCrt-window.
That does not work with a DLL: The consequence of the try, to write into
a WinCrt-window from within a DLL, is a runtime error or a complete
missing of the output. Under DOS this problem will not occur.
When using the Heap Debugger under Windows for a DLL, it is absolutely
necessary to dump the report into a file. Herefor the switch
"REPORT-TO-FILE" was prepared (see "Compilerswitches in USEHDEB").
___ Program Instances (Windows) ________________________________________
When under windows a program, that links the Heap Debugger is started
in several instances, the Heap Debugger will be installed only for the
first instance. The following instances automatically use the already
installed Heap Debugger. The output of the report will not be done until
the ending of the last active instance of that program. The report then
contains all wrong heap operations, that were done in all instances of
that program.
___ Interrupts ________________________________________________________
The Heap Debugger needs three free software interrupts. This means that
when the Heap Debugger is installed it changes three free interrupt
vectors and releases them at the end of the program. The Heap Debugger
finds the free vectors itself within the range 78h to FFh. From this
range you can exclude single vectors if you need some special vectors
for own purposes. To do so you must change the parameter of the command
"HeapDebInit([])". Change the empty set to set of vectors that you want
be be left unchanged, e.g. "HeapDebInit([$F0..$FF]).
___ Stability and Performance __________________________________________
As already explained the Heap Debugger should not be used as a part of a
finished application. The Heap Debugger should only be used during the
developing phase as a debugging tool.
The permanent use of the Heap Debugger during the software development
can help stabilize the developed software a lot and shorten the
developmenting time.
On the other hand the Heap Debugger can be a potential cause for
program crashes, even if this has not been discovered yet. Following
facts should be watched:
- The Heap Debugger not only controls the correct usage of the heap
memory. It also requires meap memory itself for this task. If a
program occasionally has to allocate a large number of heap memory
blocks, so the amount of needed extra memory for the Heap Debugger
can be high. You should count with an extra 24 bytes for each
allocated (and not yet deallocated) memory block.
Page 14
- The execution of the Heap Debugger requires extra space on the stack,
as well as the execution of the memory operations and also the
output of the report in the exit-procedure of the unit UseHDeb. Please
notice that no stack-checks are done so that a lack of stack-space
will cause a program crash.
- When fatal errors in the application program are made in using the
meap that can bring the program to a collapse. There might be
constallations, in that the program doesn't crash when the Heap
Debugger isn't linked. Nevertheless the causing error is dangerous.
Such crashes can for instance happen, when the application tries to
release a not allocated memory block.
- The Heap Debugger needs for its work additional CPU-time. The more
memory blocks are allocated, the more CPU-time the Heap Debugger
requires, especially for releasing memory.
- The Heap Debugger requires, as in the previous section mentioned, for
its work three free software interrupts. The tree vectors are set to
the addresses of three functions within the Heap Debugger and restored
at the end of the program. When a program suddenly ends because of a
fatal error and the exit procedure of the Unit UseHDeb insn't
executed, then the interrupt vectors are not set to their old values.
If such crashes happen very often, the Heap Debugger might not be able
to find any free Interrupts and wont start.
___Intervention possibilities for the Programmer _______________________
If you perhaps like to change the appearance of the Heap Debugger Report
you can modify the sourcecode of the unit UseHDeb. Changes are only
allowed for your own, non-commercial use.
Beside the unit UseHDeb offers the following constants, which can be
changed during at runtime:
1) SuspendHeapdeb : Boolean = false;
If this constant is set to TRUE at runtime, then there will be no heap
operations recorded by the Heap Debugger. After the reconversion of the
value to FALSE the Heap Debugger will work normal. This can be
useful to prevent quasi-static variables being listed in the report.
2) RecordZeroSize : Boolean = false;
As long as this constant is FALSE, allocations and deallocations with
the a length of zero be ignored by the Heap Debugger. Because such
operations are just disfigurements and (as far as we know) cant make
damage, this constant is preadjusted to FALSE.
3) RTEOnWrongSizedFree : Byte = 0;
If in this constant is not zero, every deallocation, that doesn't have
the same length as the fitting allocation (Flag "S"), will cause a
runtime error immediately. The number of the runtime error is
determined by this constant.
4) RTEOnUnknownFree : Byte = 0;
If in this constant is not zero, every deallocation with not matching
allocation (Flag "M"), will cause a runtime error immediately. The
number of the runtime error is determined by this constant.
Page 15
KNOWN LIMITATIONS AND PROBLEMS _________________________________________
___ Mark/Release _______________________________________________________
The Heap Debugger doesn't work with these commands. The usage of Release
can cause the records of the Heap Debugger being destructed.
However the commands Mark and Release are seldomly used, because
they bring other problem with them in general. Probably they are still
in the newest version of the compiler because of the compatibility. The
usage of Mark and Release we generally do not advise. Mark and Release
are only available under DOS.
___ MemAllocSeg ________________________________________________________
The function MemAllocSeg in the unit Memory (under Windows: OMemory)
is a big problem for the Heap Debugger: The job of this function
is, to allocate a heap memory area, who's start address is exactly at
the start of a memory segment (at the offset address 0000). To reach
this, the function MemAllocSeg must use some tricks. We have to make
differences between the target-platforms:
Real Mode:
To allocate a heap memory area with the offset address 0000, the
function MemAllocSeg reserves with GetMem initially a little larger
area, to afterwards immediately release with FreeMem a small part
(8 Bytes), that is either located at the start or at the end of the
just allocated area. Altho this is an offence against the rules, this
trick isn∩t really illegal. The Heap Debugger "watches" these operations
and will later list them in its report. This can for instance
look like this:
program TEST;
uses UseHDeb, Memory;
var p: pointer;
begin
{...}
p := MemAllocSeg(100);
FreeMem(p, 100);
end.
HEAP-DEBUGGER-DIAGNOSIS:
1 pointers were registered
3 debug-entries available
list (Y/N) ? y
No Pointer Size Flags Caller File Line
1 1A4D:0000 112 S 020B[1438]:001F MEMORY.PAS 327
1A53:0008 8 F M 020B[1438]:00D5 MEMORY.PAS 355
1A4D:0000 100 FS 0000[122D]:003A TEST.PAS 7
Or so:
Page 16
HEAP-DEBUGGER-DIAGNOSIS:
1 pointers were registered
3 debug-entries available
list (Y/N) ? y
No Pointer Size Flags Caller File Line
1 1531:0008 112 S 020C[0F1A]:001F MEMORY.PAS 327
1531:0008 8 FS 020C[0F1A]:00D5 MEMORY.PAS 355
1532:0000 100 F M 0000[0D0E]:004A TEST.PAS 7
The programmer is more or less being forced, to accept such operations
altho they appear risky.
Protected Mode (DOS/DPMI):
Here the function MemAllocSeg has it easier then in Real Mode:
It just calls the function "MemAllocateBlock", which is made available
by RTM.EXE that calls a corresponding DPMI-function. Through this
a heap memory block is allocated, that starts at the offset address
0000. As already explained in section "Global and Local Heap",
the Heap Debugger notices nothing of this. The releasing of this
heap memory block is normally done with the function FreeMem, about
what the Heap Debugger takes notice. Our test program would show in
the protected mode the following report:
HEAP-DEBUGGER-DIAGNOSIS:
0 pointers were registered
1 debug-entries available
list (Y/N) ? y
No Pointer Size Flags Caller File Line
059F:0000 100 F M 0001[0547]:003D TEST.PAS 7
Windows:
Here we have the same situation as in the protected mode under DOS,
except that the MemAllocSeg uses the function "GlobalAlloc" to allocate
heap memory at the offset address 0000. Since this is a Global Heap-
operation, the Heap Debugger will not notice anything. The releasing
of this heap memory area with FreeMem will be registered. The
consequence for the Heap Debugger is the same as in the protected mode.
___ BGI ________________________________________________________________
During the initializing of BGI-Drivers the same phenomenon as described
in the section "MemAllocSeg" might occur. Mostlikely the BGI-Drivers or
the unit Graph have their own implementation of the function
"MemAllocSeg".
___ TMemoryStream ______________________________________________________
The method "ChangeListSize" of this stream-object uses MemAllocSeg,
which was described above.
Page 17
___ Heap Overrun _______________________________________________________
The Heap Debugger, that is supposed to control the heap operations of a
program, also needs heap memory for its work. In case the heap debugger
cannot request anymore heap memory, because this is used up, then there
will be an internal error number 203 reported. When the main program
defines a heaperror-function, then this will be executed when a
heap allocation in the Heap Debugger fails.
___ Program Break ______________________________________________________
When a program, that uses the Heap Debugger, breaks execution without
the exit-procedure of the unit UseHDeb is being run, then the by the
Heap Debugger changed software interrupt vectors will not be restored.
Non restored interrupt vectors, that are not used elsewhere, are of no
danger. During a new Initialization of the Heap Debugger by a repeated
run, there will be three other interrupt vectores searched. If the
"hard" breaks repeat (approx. 40 times), there will sometime be no more
free interrupt vectores and the Heap Debugger∩s initialization will
fail. This then can only be fixed by a reboot of the computer.
___ WINCRT _____________________________________________________________
If the main program is already using a WinCrt-Window and this is not
closed with DoneWinCrt, before the exit-procedure of the Unit UseHDeb is
run, then typically 2000 bytes of heap memory stay allocated, that then
is listed in the Heap Debugger Report.
Anyhow you should not be program a DoneWinCrt-command into the main
program, because this brings up new problems.
As already described in the section "DLLs", the Heap Debugger cannot
dump into a WinCrt-window when a DLL is being used.
In case of doubt you should try to take advantage of the possibility of
the dumping the report into a file.